//
// Created by u on 23-7-28.
//

#ifndef CLOUD_CHINT_SRC_CONFIG_HPP_
#define CLOUD_CHINT_SRC_CONFIG_HPP_


#include <iostream>
#include <unordered_map>
#include <XLogger.hpp>
#include <yaml-cpp/yaml.h>


static const std::vector<std::string> configList{
	"local",
	"cloud"
};

class Config {
public:

	Config(const std::string& path)
		: configPath_(path){
		LOG_DEBUG("configPath: {}", configPath_);
		read(connectConfigInfos);
	}

	bool read(std::unordered_map<std::string, MqttConnectInfo>& result) {
		if (configPath_.empty())
			return false;
		auto parseStr = [&](const YAML::Node &node, std::string &result) -> bool {
		  const auto &iterms = node;
		  if (!iterms.IsDefined()) {
			  return false;
		  }
		  if (iterms.IsNull()) {
			  result = "";   // 为空时默认填 ""
		  } else if (iterms.IsScalar()) {
			  result = iterms.as<std::string>();
		  }
		  return true;
		};
		auto parseNum = [&](const YAML::Node &node, int &result) -> bool {
		  const auto &iterms = node;
		  if (!iterms.IsDefined()) {
			  return false;
		  }
		  if (iterms.IsNull()) {
			  result = -1;   // 为空时默认填 ""
		  } else if (iterms.IsScalar()) {
			  result = iterms.as<std::int32_t>();
		  }
		  return true;
		};
		auto parseBool = [&](const YAML::Node &node, bool &result) -> bool {
		  const auto &iterms = node;
		  if (!iterms.IsDefined()) {
			  return false;
		  }
		  if (iterms.IsNull()) {
			  result = false;
		  } else if (iterms.IsScalar()) {
			  result = iterms.as<bool>();
		  }
		  return true;
		};

		try {
			YAML::Node doc = YAML::LoadFile(configPath_);
			for (const auto& config : configList) {
				if (doc[config].IsDefined()) {
					MqttConnectInfo info;
					parseStr(doc[config]["server"], info.server);
					parseNum(doc[config]["port"], info.port);
					parseStr(doc[config]["clientID"], info.clientID);
					parseStr(doc[config]["user"], info.user);
					parseStr(doc[config]["passwd"], info.passwd);
					parseBool(doc[config]["cleanSession"], info.cleanSession);
					parseNum(doc[config]["keepAlive"], info.keepAlive);
					result.insert(std::make_pair(std::string(config), info));
				}
			}
			return true;
		} catch (const YAML::Exception& e) {
			// 捕获 YAML 异常，并进行错误处理
			std::cerr << "YAML parsing error: " << e.what() << std::endl;
			return false; // 或者抛出异常等其他错误处理方式
		}
	}

	void print() {
		for (const auto& connectConfigInfo : connectConfigInfos) {
			LOG_DEBUG("--> {}", connectConfigInfo.first);
			LOG_DEBUG("server: {}", connectConfigInfo.second.server);
			LOG_DEBUG("port: {}", connectConfigInfo.second.port);
			LOG_DEBUG("clientID: {}", connectConfigInfo.second.clientID);
			LOG_DEBUG("user: {}", connectConfigInfo.second.user);
			LOG_DEBUG("passwd: {}", connectConfigInfo.second.passwd);
			LOG_DEBUG("cleanSession: {}", connectConfigInfo.second.cleanSession);
			LOG_DEBUG("keepAlive: {}", connectConfigInfo.second.keepAlive);
			LOG_DEBUG("");
		}
	}
public:
	std::unordered_map<std::string, MqttConnectInfo> connectConfigInfos;
private:
	std::string configPath_;
};

#endif //CLOUD_CHINT_SRC_CONFIG_HPP_
